package com.team.utils.util_wx.common;

import com.thoughtworks.xstream.XStream;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class Util {

	/**
	 * 通过反射的方式遍历对象的属性和属性值，方便调试
	 *
	 * @param o
	 *            要遍历的对象
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	public static void reflect(Object o) throws Exception {
		Class cls = o.getClass();
		Field[] fields = cls.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			Field f = fields[i];
			f.setAccessible(true);
		}
	}

	public static byte[] readInput(InputStream in) throws IOException {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int len = 0;
		byte[] buffer = new byte[1024];
		while ((len = in.read(buffer)) > 0) {
			out.write(buffer, 0, len);
		}
		out.close();
		in.close();
		return out.toByteArray();
	}

	public static String inputStreamToString(InputStream is) throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		int i;
		while ((i = is.read()) != -1) {
			baos.write(i);
		}
		return baos.toString();
	}

	public static InputStream getStringStream(String sInputString) {
		ByteArrayInputStream tInputStringStream = null;
		if (sInputString != null && !sInputString.trim().equals("")) {
			tInputStringStream = new ByteArrayInputStream(sInputString.getBytes());
		}
		return tInputStringStream;
	}

	@SuppressWarnings("rawtypes")
	public static Object getObjectFromXML(String xml, Class tClass) {
		// 将从API返回的XML数据映射到Java对象
		XStream xStreamForResponseData = new XStream();
		xStreamForResponseData.alias("xml", tClass);
		xStreamForResponseData.ignoreUnknownElements();// 暂时忽略掉一些新增的字段
		return xStreamForResponseData.fromXML(xml);
	}

	public static String getStringFromMap(Map<String, Object> map, String key, String defaultValue) {
		if (key == "" || key == null) {
			return defaultValue;
		}
		String result = (String) map.get(key);
		if (result == null) {
			return defaultValue;
		} else {
			return result;
		}
	}

	public static int getIntFromMap(Map<String, Object> map, String key) {
		if (key == "" || key == null) {
			return 0;
		}
		if (map.get(key) == null) {
			return 0;
		}
		return Integer.parseInt((String) map.get(key));
	}

	/**
	 * 读取本地的xml数据，一般用来自测用
	 *
	 * @param localPath
	 *            本地xml文件路径
	 * @return 读到的xml字符串
	 */
	public static String getLocalXMLString(String localPath) throws IOException {
		return Util.inputStreamToString(Util.class.getResourceAsStream(localPath));
	}

	/**
	 * Build wxpay scan qrcode url. call QRCode.from(String) to build qrcode
	 *
	 * @see <a href=
	 *      "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4">https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4</a>
	 * @see <a href=
	 *      "https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=4_3">https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=4_3</a>
	 * @param product_id
	 *            the id of the product
	 * @return qrcode url
	 */
	public static String buildQRcodeUrl(String product_id) {
		Map<String, Object> map = new HashMap<>();
		map.put("appid", Configure.getAppid());
		map.put("mch_id", Configure.getMchid());
		map.put("time_stamp", System.currentTimeMillis() / 1000);
		map.put("nonce_str", RandomStringGenerator.getRandomStringByLength(Configure.NONCE_STR_LENGTH));
		map.put("product_id", product_id);
		String sign = Signature.getSign(map);
		// map.put("sign", sign);
		String url = String.format("%s?%s", Configure.QRCODE_API, param(map));
		url += "&sign=" + sign;
		return url;
	}

	/**
	 * Build Url param from map
	 *
	 * @param map
	 *            source
	 * @return url param
	 */
	public static String param(Map<String, Object> map) {
		ArrayList<String> list = new ArrayList<String>();
		for (Map.Entry<String, Object> entry : map.entrySet()) {
			if (entry.getValue() != "") {
				list.add(entry.getKey() + "=" + entry.getValue() + "&");
			}
		}
		int size = list.size();
		String[] arrayToSort = list.toArray(new String[size]);
		Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < size; i++) {
			sb.append(arrayToSort[i]);
		}
		return sb.substring(0, sb.length() - 1);
	}
}
